package com.bxj.wxtt.utils;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


@Component
public final class HtmlUtil {


	/**
	 * 替换html中的占位符(形如：$$$[2,page])
	 * @param html 原html
	 * @param version 客户端版本
	 * @param platformGroupId 平台组ID
	 * @param isForBi 是否为BI使用
	 * @return 替换后的html
	 */
	public String replacePlaceholderInHtml(String html, String version, int platformGroupId, boolean isForBi) {
		return replacePlaceholderInHtml(html, version, platformGroupId, null, isForBi);
	}

	/**
	 * 替换html中的占位符(形如：$$$[2,page]) <br>
	 * 在这个方法中，根据每种需要替换的html代码类型，然后各自又调用了具体的子方法进行实现
	 * @param html 原html
	 * @param version 客户端版本
	 * @param platformGroupId 平台组ID
	 * @param software 客户端的软件型号
	 * @param isForBi 是否为BI使用
	 * @return 替换后的html
	 */
	public String replacePlaceholderInHtml(String html, String version, int platformGroupId, String software,
			boolean isForBi) {
		// 解析需要替换的对象，及其位置信息
		List<ReplaceItemBO> replaceItemList = getReplaceItemFromHtml(html);

		// 归类
		Map<String, List<ReplaceItemBO>> replaceItemMap = classifyByType(replaceItemList);
		// 获取用来替换的内容，并存储于ReplaceItem对象的dest属性中
		for (Entry<String, List<ReplaceItemBO>> entry : replaceItemMap.entrySet()) {
			String type = entry.getKey();
			List<ReplaceItemBO> childlist = entry.getValue();
			if  ("v".equals(type)) {
				replaceVersion(childlist, version);
			} else if ("channel".equals(type)) {
				replaceChannel(childlist, version);
			}
		}

		
		// 替换，将ReplaceItem对象占的位置[ReplaceItemBO.start, ReplaceItemBO.end]替换成ReplaceItem.dest所描述的内容
		StringBuilder sb = new StringBuilder();
		int i = 0;
		for (ReplaceItemBO replaceItem : replaceItemList) {
			sb.append(html.substring(i, replaceItem.getStart()));
			if (replaceItem.getDest() != null) {
				sb.append(replaceItem.getDest());
			}
			i = replaceItem.getEnd();
		}
		sb.append(html.substring(i));
		return sb.toString();
	}

	/**
	 * 从html中解析出需要替换的对象(形如：$$$[2,page])，及其位置信息<br>
	 * 通过正则表达式来进行匹配替换
	 * @param html 需要替换的html代码
	 * @return 替换之后的对象集合
	 */
	private List<ReplaceItemBO> getReplaceItemFromHtml(String html) {
		List<ReplaceItemBO> list = new ArrayList<ReplaceItemBO>();
		String regex = "\\$\\$\\$\\[(.+?),(\\w+)\\]"; // 形如"$$$[2,page]"

		// 表达式对象
		Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
		// 创建 Matcher 对象
		Matcher m = p.matcher(html);
		int i = 0;
		while (m.find(i)) {
			int start = m.start();
			int end = m.end();
			String src = m.group();
			String strBookId = m.group(1);
			String type = m.group(2);

			ReplaceItemBO ri = new ReplaceItemBO();
			ri.setSrc(src);
			ri.setArg(strBookId);
			ri.setType(type);
			ri.setStart(start);
			ri.setEnd(end);
			list.add(ri);

			i = end;
		}
		return list;
	}

	/**
	 * 该工具类的私有 方法:<br>
	 * 按ReplaceItem集合对象中每个对象的type属性归类成map形式(形如：Map<a.type,[a]>)
	 * @param list 集合对象
	 * @return Map对象 keyset[a.type:a]
	 */
	private Map<String, List<ReplaceItemBO>> classifyByType(List<ReplaceItemBO> list) {
		Map<String, List<ReplaceItemBO>> map = new HashMap<String, List<ReplaceItemBO>>();
		for (ReplaceItemBO replaceItem : list) {
			List<ReplaceItemBO> tempList = map.get(replaceItem.getType());
			if (tempList == null) {
				tempList = new ArrayList<ReplaceItemBO>();
				map.put(replaceItem.getType(), tempList);
			}
			tempList.add(replaceItem);
		}
		return map;
	}



	/**
	 * 用传入的客户端版本号，来替换ReplaceItemBO集合列表中的版本代码
	 * @param replaceItemList 待替换的集合列表
	 * @param version 客户端版本号
	 */
	private void replaceVersion(List<ReplaceItemBO> replaceItemList, String version) {
		for (ReplaceItemBO replaceItem : replaceItemList) {
			replaceItem.setDest(version);
		}
	}

	/**
	 * 根据传入的版本号，获取出对应的渠道号(14.1.23.4324 最后一位)，替换ReplaceItemBO集合中的渠道代码
	 * @param replaceItemList 待替换的集合
	 * @param version 客户端版本号
	 */
	private void replaceChannel(List<ReplaceItemBO> replaceItemList, String version) {
		Integer channel = null;
		Pattern versionPatter = Pattern.compile("(\\d+).(\\d+).(\\d+).(\\d+)$");
		Matcher m = versionPatter.matcher(version);
		if (m.find()) {
			channel = Integer.valueOf(m.group(4));
		}
		for (ReplaceItemBO replaceItem : replaceItemList) {
			if (channel == null) {
				replaceItem.setDest("");
				continue;
			}
			int index = replaceItem.getArg().indexOf("_");
			if (index == -1) {
				replaceItem.setDest("");
				continue;
			} else {
				Integer destChannel = null;
				try {
					destChannel = Integer.valueOf(replaceItem.getArg().substring(0, index));
				} catch (Exception e) {
					replaceItem.setDest("");
					continue;
				}
				if (channel.intValue() == destChannel.intValue()) {
					replaceItem.setDest(replaceItem.getArg().substring(index + 1).replace("$$$[v]", version));
				} else {
					replaceItem.setDest("");
					continue;
				}
			}
		}
	}


	/**
	 * 替换software对象
	 * @param replaceItemList 待替换的集合
	 * @param software 客户端机型软件
	 */
	private void replaceSoftware(List<ReplaceItemBO> replaceItemList, String software) {
		String value = null;
		for (ReplaceItemBO replaceItem : replaceItemList) {
			if (software == null) { //未能识别出机型
				replaceItem.setDest("");
			} else {
				value = replaceItem.getArg();
				if (value.indexOf(software.toLowerCase() + "_") != -1) {
					replaceItem.setDest(value.replaceAll(software.toLowerCase() + "_", ""));
				} else {
					replaceItem.setDest("");
				}
			}
		}
	}



}
